home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 328 / v_m_6502.c < prev    next >
C/C++ Source or Header  |  1988-10-29  |  24KB  |  778 lines

  1.  
  2. /***************************************************************************
  3.  
  4.    V_M_6502.C  -  A virtual machine emulator
  5.  
  6.    (c) 1986 Darek Mihocka
  7.  
  8.    People I'd like to thank before they sue me:
  9.     - Ignac Kolenko for helping me code and debug this program.
  10.     - Megamax Inc. for making code a joy to write.
  11.     - everyone else in Toronto who encouraged me to write this program.
  12.  
  13.    Microprocessor  : 6502 @ 250kHz
  14.    Hardware        : 48K Apple ][
  15.    Operating system: none, but one can be loaded from disk
  16.  
  17.    Last update: December 31, 1986
  18.  
  19.  ***************************************************************************/
  20.  
  21. #include <stdio.h>
  22. #include <osbind.h>
  23.  
  24. #define LOOP while(1)
  25. #define print(x) put_line(x)
  26. #define put(x) outchar(x)
  27. #define CR print("\n\r")
  28. #define BEL '\007'
  29. #define CLS print("\033E")
  30.  
  31. static char *hex= {"0123456789ABCDEF"} ;
  32.  
  33. char buf[80] ,        /* monitor line input buffer */
  34.      ch ,             /* character at buf[tp] */
  35.      asc[17] ,        /* buffer for ASCII dump */
  36.      hardcopy,        /* if non-zero dumps to printer */
  37.      *mem,            /* 65536 bytes to simulate 6502 memory */
  38.      *stat,           /* status bits for each byte */
  39.      *scr,            /* pointer to start of screen */
  40.      *scr_emul ;      /* pointer to start of emulation screen */
  41.  
  42. int  len,             /* length of inputted line */
  43.      tp ,             /* pointer to current character in buf[] */
  44.      MAXCOL ,
  45.      MAXROW ,
  46.      MAXBYTE ,
  47.      hand,            /* disk handle */
  48.      mode ;           /* screen resolution */
  49.  
  50. int cpu ;             /* type of cpu to emulate */
  51. unsigned int pc ,     /* program counter (16 bits) */
  52.              ea ;
  53. unsigned char a,x,y,sp,ir, p, trace ;
  54.  
  55. struct DTA {                   /* for disk directories */
  56.          char reserved[21] ;
  57.          char attrib ;
  58.          int time, date ;
  59.          long size ;
  60.          char fname[11] ;
  61.        }  ioblock ;
  62.  
  63. struct disk_info {
  64.          long b_free,b_total,b_sec_siz,b_cl_siz ; } diskblock ;
  65.  
  66. #include "V_M_HDWR.INC"
  67. #include "V_M_OPS.INC"
  68.  
  69. /*********************************************************************/
  70.  
  71. help () {
  72.  
  73.     CR ;
  74.     print("  *** ST TRANSFORMER DEMO ***\n\r") ;
  75.     CR ; CR ;
  76.     print("  Syntax: ( all numbers are in hex )\n\r") ;
  77.     CR ;
  78.     print("    ssss - starting address\n\r") ;
  79.     print("    eeee - ending address\n\r") ;
  80.     print("    dddd - destination address\n\r") ;
  81.     print("    nn   - an 8 bit value\n\r") ;
  82.     CR ;
  83.     print("  Command Summary:\n\r") ;
  84.     CR ;
  85.     print("    : ssss nn [nn [nn [nn ...]]] - ") ;
  86.     print("change contents of memory starting from ssss\n\r") ;
  87.     print("    B                            - ") ;
  88.     print("boot up the virtual computer\n\r") ;
  89.     print("    D ssss [eeee]                - ") ;
  90.     print("display memory from ssss to eeee or one line\n\r") ;
  91.     print("    G ssss                       - ") ;
  92.     print("start emulating at ssss \n\r") ;
  93.     print("    H nn                         - ") ;
  94.     print("nn is non-zero for hardcopy \n\r") ;
  95.     print("    I                            - ") ;
  96.     print("index of binary files on the disk\n\r") ;
  97.     print("    L ssss [eeee]                - ") ;
  98.     print("disassemble from ssss to eeee or one page\n\r") ;
  99.     print("    M ssss eeee dddd             - ") ;
  100.     print("move memory block from ssss to dddd\n\r") ;
  101.     print("    R file                       - ") ;
  102.     print("read memory block \n\r") ;
  103.     print("    S [ssss]                     - ") ;
  104.     print("single step at aaaa or program counter\n\r") ;
  105.     print("    T [ssss]                     - ") ;
  106.     print("trace at aaaa or program counter\n\r") ;
  107.     print("    V                            - ") ;
  108.     print("view emulated screen display       \n\r") ;
  109.     print("    W ssss eeee file             - ") ;
  110.     print("save memory block from ssss to dddd\n\r") ;
  111.     print("    X                            - ") ;
  112.     print("exit this great program\n\r") ;
  113.     CR ; CR ;
  114.  
  115.   }
  116.  
  117. outchar(x) char x ; {
  118.  
  119.   Bconout (2,x) ;     /* print to screen */
  120.   if ((hardcopy)&&(Bconstat(0)))
  121.     Bconout (0,x) ;   /* print to printer */
  122. }
  123.  
  124. put_line(lin)
  125.   char *lin ; {         /* write string to screen */
  126.  
  127.   char c ;
  128.   while (c=*lin++) put (c) ;
  129. }
  130.  
  131.  
  132. get_line(maxc) int maxc ; {      /* get line in buf[], set tp and len */
  133.  
  134.   long key ;      /* scan code and character code returned by Bconin */
  135.   len = 0 ;       /* initialize input line length to 0 */
  136.  
  137.   LOOP {
  138.     key = Bconin(2) ;                    /* get a key */
  139.     ch = (char) key ;                    /* isolate character code */
  140.     if (ch>='a' && ch<='z') ch -= 32 ;   /* lowercase becomes uppercase */
  141.     if (ch>=' ' && ch <='_') {           /* if it's printable */
  142.       put(ch) ;                          /* then print it and store it */
  143.       buf[len++] = ch ;
  144.      }                                   /* if Backspace, delete last */
  145.     if (ch==8 && len>0) {                /* character and reduce buffer */
  146.       print("\b \b") ;
  147.       len-- ;
  148.      }
  149.     if (len==0 && ch==0) {                /* if special key */
  150.       ch = (char) (key>>16) ;             /* get scan code */
  151.       if (ch==0x47) CLS ;                 /* is it Home? */
  152.       if (ch==0x62) help() ;              /* is it Help? */
  153.       break ;                             /* break out of loop */
  154.      }
  155.                         /* stay in loop until buffer full or Return pressed */
  156.     if (len==maxc || ch==13 || ch=='\n' || ch == '\033') break ;
  157.    }
  158.   CR ;
  159.   buf[len] = 0 ;        /* terminate input line with a null character */
  160.   tp = 0 ;              /* text pointer points to first character */
  161.  
  162. }
  163.  
  164.  
  165. skip_space ()           /* advance tp to point to non-space */
  166. {
  167.   while ((ch=buf[tp])==' ' && tp<len) tp++ ;
  168. }
  169.  
  170.  
  171. skip_blank ()            /* advance tp to point to non-blank */
  172. {
  173.   while (((ch=buf[tp])<'0' || (ch>'9' && ch<'A') || (ch>'F')) && tp<len) tp++ ;
  174. }
  175.  
  176.  
  177. unsigned char get_byte () {    /* return 8 bit value at tp */
  178.  
  179.   unsigned char byte=0, digit=0 ;
  180.  
  181.   skip_blank() ;
  182.   while ((tp<len) && (                           /* find next hex character */
  183.            ((ch = buf[tp]) >='0' && ch<='9') ||
  184.            (ch>='A' && ch<='F')
  185.            )
  186.          && (digit++<2) ) {
  187.     byte <<= 4 ;
  188.     byte += (ch>='0' && ch<='9') ? ch-48 : ch-55 ;
  189.     tp++ ;
  190.    }
  191.   return (byte) ;
  192. }
  193.  
  194.  
  195.  
  196. unsigned int get_addr () {    /* return 16 bit value at tp */
  197.  
  198.   unsigned int addr=0, digit=0 ;
  199.  
  200.   skip_blank() ;
  201.   while ( (((ch = buf[tp]) >='0' && ch<='9')
  202.                || (ch>='A' && ch<='F'))
  203.                && (digit++<4) ) {
  204.     addr <<= 4 ;
  205.     addr += (ch>='0' && ch<='9') ? ch-48 : ch-55 ;
  206.     tp++ ;
  207.    }
  208.   return (addr) ;
  209. }
  210.  
  211.      /* disassemble #line commands starting at current pc */
  212.  
  213. disasm(line) int line ; {
  214.  
  215.   int bits, modes ;
  216.   unsigned char opcode ;
  217.   long crunch ;
  218.  
  219.   while (line--) {
  220.     showpc() ;
  221.     opcode = *(mem+pc) ;
  222.     crunch = mnemonics[opcode] ;
  223.  
  224.     modes = crunch&0x0FL ;
  225.  
  226.     showhex(pc) ;
  227.     put(' ') ;
  228.  
  229.     switch (modes) {
  230.  
  231.       case 0x00 :
  232.       case 0x0A : print ("      ") ;
  233.                   break ;
  234.  
  235.       case 0x01 :
  236.       case 0x02 :
  237.       case 0x03 :
  238.       case 0x04 :
  239.       case 0x05 :
  240.       case 0x06 :
  241.       case 0x0B : showhex(pc+1) ;
  242.                   print ("    ") ;
  243.                   break ;
  244.  
  245.       case 0x07 :
  246.       case 0x08 :
  247.       case 0x09 :
  248.       case 0x0C : showhex(pc+1) ;
  249.                   put(' ') ;
  250.                   showhex(pc+2) ;
  251.                   put(' ') ;
  252.                   break ;
  253.      }
  254.  
  255.     for (bits=24 ; bits >0 ; bits -=8 ) {
  256.       put((char)(crunch>>24)) ;
  257.       crunch <<= 8 ;
  258.      }
  259.     put (' ') ;
  260.  
  261.     pc++ ;
  262.     switch (modes) {
  263.  
  264.       case 0x00 : print ("         ") ;
  265.                   break ;
  266.  
  267.       case 0x01 : print (" #$") ;
  268.                   showhex(pc++) ;
  269.                   print ("    ") ;
  270.                   break ;
  271.  
  272.       case 0x02 : print(" $") ;
  273.                   showhex(pc++) ;
  274.                   print ("     ") ;
  275.                   break ;
  276.  
  277.       case 0x03 : print (" $") ;
  278.                   showhex(pc++) ;
  279.                   print (",X") ;
  280.                   print ("   ") ;
  281.                   break ;
  282.  
  283.       case 0x04 : print (" $") ;
  284.                   showhex (pc++) ;
  285.                   print (",Y") ;
  286.                   print ("   ") ;
  287.                   break ;
  288.  
  289.       case 0x05 : print (" ($") ;
  290.                   showhex (pc++) ;
  291.                   print (",X)") ;
  292.                   print (" ") ;
  293.                   break ;
  294.  
  295.       case 0x06 : print (" ($") ;
  296.                   showhex (pc++) ;
  297.                   print ("),Y") ;
  298.                   print (" ") ;
  299.                   break ;
  300.  
  301.       case 0x07 : print (" $") ;
  302.                   showhex (pc+1) ;
  303.                   showhex (pc) ;
  304.                   print ("   ") ;
  305.                   pc +=2 ;
  306.                   break ;
  307.  
  308.       case 0x08 : print (" $") ;
  309.                   showhex (pc+1) ;
  310.                   showhex (pc) ;
  311.                   pc +=2 ;
  312.                   print (",X") ;
  313.                   print (" ") ;
  314.                   break ;
  315.  
  316.       case 0x09 : print (" $") ;
  317.                   showhex (pc+1) ;
  318.                   showhex (pc) ;
  319.                   pc +=2 ;
  320.                   print (",Y") ;
  321.                   print (" ") ;
  322.                   break ;
  323.  
  324.       case 0x0A : print (" A") ;
  325.                   print ("       ") ;
  326.                   break ;
  327.  
  328.       case 0x0B : print (" $") ;
  329.                   showaddr (pc + 1 + (int)((char)(*(mem+pc)))) ;
  330.                   print ("   ") ;
  331.                   pc ++ ;
  332.                   break ;
  333.  
  334.       case 0x0C : print (" ($") ;
  335.                   showhex(pc+1) ;
  336.                   showhex(pc) ;
  337.                   put (')') ;
  338.                   print (" ") ;
  339.                   pc+=2 ;
  340.                   break ;
  341.  
  342.       default :   break ;
  343.      }
  344.     if (!trace) CR ;
  345.  
  346.    }
  347. }
  348.  
  349. showreg() {
  350.  
  351.   print ("PC=") ;  showpc() ;
  352.   print ("A=") ;   showbyte(a) ;
  353.   print (" X=") ;  showbyte(x) ;
  354.   print (" Y=") ;  showbyte(y) ;
  355.   print (" S=") ;  showbyte(sp) ;
  356.   print (" P=") ;  showbyte(p) ;
  357.   print (" ") ;
  358.   (p&NBIT) ? put('N') : put ('.') ;
  359.   (p&VBIT) ? put('V') : put ('.') ;
  360.   (p&BBIT) ? put('B') : put ('.') ;
  361.   (p&DBIT) ? put('D') : put ('.') ;
  362.   (p&IBIT) ? put('I') : put ('.') ;
  363.   (p&ZBIT) ? put('Z') : put ('.') ;
  364.   (p&CBIT) ? put('C') : put ('.') ;
  365.   put (' ') ;
  366. }
  367.  
  368.  
  369.   /* routine to single step, trace, or execute at current pc */
  370.  
  371. emulate (count, mode) int count, mode ; {
  372.  
  373.   unsigned int pctemp ;
  374.   unsigned char ptemp ;
  375.   long usp, start_time, end_time ;
  376.  
  377.   switch (mode) {
  378.  
  379.     case 0 :       /* regular emulation */
  380.  
  381.               usp = Super(0L) ;     /* must go to supervisor mode */
  382.               show_emul() ;
  383.               execute() ;
  384.               show_scr() ;
  385.               Super(usp) ;
  386.               showreg() ;
  387.               if (trace) print ("EA: ") ;
  388.               showaddr (ea) ;
  389.               CR ;
  390.               trace=0 ;
  391.               break ;
  392.  
  393.     case 1 :       /* single step mode */
  394.               pctemp = pc ;    /* remember pc                    */
  395.               disasm(1) ; /* dissassemble current opcode    */
  396.               pc = pctemp ;    /* restore pc                     */
  397.               trace=255 ;
  398.               emulate(0,0) ;
  399.               break ;
  400.  
  401.     case 2 :       /* trace mode */
  402.               p &= ~BBIT ;
  403.               while (count-- && !(p&BBIT)) emulate(0,1) ;
  404.               break ;
  405.  
  406.    }
  407. }
  408.  
  409. mon() {            /* the 6502 monitor */
  410.  
  411.   int quit=0 ;                  /* quit flag */
  412.   char com ;                    /* command character */
  413.   int digit, chptr, cntr ;      /* temporary variables */
  414.   unsigned addr1, addr2, addr3, byt ;
  415.   unsigned char header[6] ;
  416.  
  417.   do {
  418.     print ("\n\r>") ;           /* print prompt */
  419.     get_line(MAXCOL) ;          /* get a line of input */
  420.     skip_space() ;              /* skip any leading spaces */
  421.     com = buf[tp++] ;             /* get command character */
  422.  
  423.     if (com!='R') addr1 = get_addr() ;  /* no numbers for R */
  424.  
  425.     switch(com) {
  426.  
  427.       case '\000' :        /* empty line or comment is ignored */
  428.       case ';' : break ;
  429.  
  430.       case 'X' : quit++ ;  /* X to quit */
  431.                  break ;
  432.  
  433.       case 'M' : pc = addr1 ;          /* block memory move */
  434.                  addr2 = get_addr() ;
  435.                  addr3 = get_addr() ;
  436.                  while (addr1<=addr2) *(mem+addr3++) = *(mem+addr1++) ;
  437.                  break ;
  438.  
  439.       case ':' : pc = addr1 ;          /* modify memory */
  440.                  skip_blank() ;
  441.                  while (buf[tp] && (tp<len)) {
  442.                    *(mem+pc++) = get_byte() ;
  443.                    skip_blank() ;
  444.                   }
  445.                  break ;
  446.  
  447.       case 'D' : pc = addr1 ;        /* dump memory */
  448.                  addr2 = get_addr() ;
  449.                  if (addr2 <= addr1) addr2 = addr1 + MAXBYTE - 1 ;
  450.                  do {
  451.                    showpc() ;
  452.                    for (cntr=0; cntr<MAXBYTE; cntr++) {
  453.                      if (pc<=addr2) {
  454.                        ch = (*(mem+pc))&0x7F ;
  455.                        asc[cntr] = (ch>=32 && ch<=127) ? ch : '.' ;
  456.                        showhex(pc++) ;
  457.                        put (' ');
  458.                      }
  459.                      else {
  460.                        asc[cntr] = ' ' ;
  461.                        print ("   ") ;
  462.                       }
  463.                     }
  464.                    for (cntr=0; cntr<MAXBYTE; cntr++) put(asc[cntr]) ;
  465.                    CR ;
  466.                   } while (pc<=addr2 && pc>0x000F) ;
  467.                  break ;
  468.  
  469.       case 'L' : if (len>1) pc = addr1 ;     /* disassemble memory */
  470.                  disasm(MAXROW-4) ;
  471.                  break ;
  472.  
  473.       case 'T' : if (len>1) pc = addr1 ;     /* trace execution */
  474.                  p &= ~BBIT ;
  475.                  emulate(35,2) ;
  476.                  break ;
  477.  
  478.       case 'B' : pc = (*(mem+0xFFFD)*256)+(*(mem+0xFFFC)) ; /* RESET vector */
  479.                  p &= ~BBIT ;
  480.                  emulate(0,0) ;
  481.                  break ;
  482.  
  483.       case 'G' : pc = addr1 ;                /* execute 6502 code */
  484.                  p &= ~BBIT ;
  485.                  emulate(0,0) ;
  486.                  break ;
  487.  
  488.       case 'S' : if (len>1) pc = addr1 ;     /* step execution */
  489.                  (*emulate)(0,1) ;
  490.                  break ;
  491.  
  492.       case '.' : showreg() ;            /* dump registers */
  493.                  break ;
  494.  
  495.       case 'I' :               /* index of binary files, i.e. a directory */
  496.                 {
  497.                  int file_count=0 ;
  498.                  long fre_by ;
  499.                  Fsetdta(&ioblock) ;
  500.                  if (Fsfirst("*.BIN",0)>=0) {
  501.                    print ("Directory of binary files:") ; CR ; CR ;
  502.                    print ("filename  bytes") ; CR ;
  503.                    do {
  504.                      file_count++ ;
  505.                      for (x=0; (x<8) && (ioblock.fname[x] != '.') ;
  506.                         put(ioblock.fname[x++])) ;
  507.                      for (;x++<9;put (' ') ) ;
  508.                      if ((ioblock.size - 6L) < 65537L)
  509.                            printf ("%6ld\n",ioblock.size-6L);
  510.                      } while (Fsnext()>=0) ;
  511.                   }
  512.                  CR ;
  513.                  Dfree (&diskblock,0) ;
  514.                  fre_by = (diskblock.b_sec_siz * diskblock.b_cl_siz *
  515.                        diskblock.b_free) ;
  516.                  printf("\n%d file(s)   %ld bytes free\n",file_count,fre_by);
  517.                  fflush (stdout) ;
  518.                  break ;
  519.                 }
  520.  
  521.       case 'W' : pc = addr1 ;            /* write memory to binary file */
  522.                  addr2 = get_addr() ;
  523.                  if (addr2 < addr1) break ;
  524.                  skip_space() ;
  525.                  if (tp==len) break ;
  526.                  strncpy (&buf[len],".bin",5) ;      /* append to filename */
  527.                  if ((hand=Fcreate (&buf[tp],0))<0) break ;
  528.                  print ("Writing...") ; CR ;
  529.                  header[0] = header[1] = 255 ;
  530.                  header[2] = addr1 ;           /* lo - hi format */
  531.                  header[3] = addr1>>8 ;
  532.                  header[4] = addr2 ;
  533.                  header[5] = addr2>>8 ;
  534.                  if (Fwrite (hand,6L,header)<0) {
  535.                    print ("Write error") ; CR ;
  536.                    goto err_close ;
  537.                   }
  538.                  if (Fwrite
  539.                     (hand,(long)addr2-(long)addr1+1L,
  540.                      mem+addr1)<0) {
  541.                    print ("Write error") ; CR ;
  542.                    goto err_close ;
  543.                   }
  544.                  Fclose (hand) ;
  545.                  break ;
  546.  
  547.        err_close:
  548.                  Fclose (hand) ;
  549.                  break ;
  550.  
  551.       case 'R' : skip_space() ;                /* read binary file to memory */
  552.                  if (tp==len) break ;
  553.                  strncpy (&buf[len],".bin",5) ;
  554.                  if ((hand = Fopen (&buf[tp],0))<0) goto err_close ;
  555.                  print ("Reading...   ") ;
  556.                  if (Fread (hand,6L,header)<0) {
  557.                    print ("File not found") ; CR ;
  558.                    goto err_close ;
  559.                   }
  560.                  if (header[1]&header[0] != 255)  /* verify it's binary file */
  561.                   {
  562.                    print ("Not binary file") ;
  563.                    goto err_close ;
  564.                   }
  565.                  addr1 = header[2] + (header[3] << 8) ;
  566.                  addr2 = header[4] + (header[5] << 8) ;
  567.                  if (Fread
  568.                     (hand,(long)addr2-(long)addr1+1L,
  569.                      mem+addr1)<0) {
  570.                    print ("EOF reached") ;
  571.                    goto err_close ;
  572.                   }
  573.                  printf ("\nstart %4x  end %4x\n",addr1,addr2) ;
  574.                  Fclose (hand) ;
  575.                  break ;
  576.  
  577.       case 'H' : hardcopy = addr1 ;         /* set hardcopy on/off flag */
  578.                  break ;
  579.  
  580.       case 'V' : show_emul() ;              /* view virtual machine screen */
  581.                  getchar() ;
  582.                  show_scr() ;
  583.                  break ;
  584.  
  585.       default :  put(BEL) ;                 /* otherwise beep */
  586.  
  587.      }
  588.    } while (!quit) ;
  589. }
  590.  
  591.  
  592. showpc() {                          /* print out PC */
  593.  
  594.   int bit ;
  595.  
  596.   for (bit = 12; bit>=0; bit-=4) put (hex[(pc>>bit)&0x0F]) ;
  597.   print(": ") ;
  598. }
  599.  
  600.  
  601. showaddr(addr) unsigned int addr ;  /* print 16 bit number */
  602. {
  603.   put (hex[addr>>12]) ;
  604.   put (hex[(addr>>8)&0x0f]) ;
  605.   put (hex[(addr>>4)&0x0f]) ;
  606.   put (hex[addr&0x0f]) ;
  607. }
  608.  
  609. showhex(addr) unsigned int addr ;   /* print 8 bit number in memory */
  610. {
  611.   unsigned char byte ;
  612.  
  613.   byte = *(mem+addr) ;
  614.   put (hex[byte>>4]) ;
  615.   put (hex[byte&0x0f]) ;
  616. }
  617.  
  618. showbyte(byte) unsigned char byte ; /* print 8 bit number */
  619. {
  620.   put (hex[byte>>4]) ;
  621.   put (hex[byte&0x0f]) ;
  622. }
  623.  
  624.  
  625. col25() {               /* switch to 25 row color mode */
  626.   asm {                              /* code borrowed from HI50.PRG */
  627.         DC.W     0xA000              /* call LINEA to return some pointers */
  628.         MOVE.L   4(A1),A1            /* get pointer to 8x8 font data */
  629.         MOVE.L   72(A1),-0x0A(A0)    /* beats me?? */
  630.         MOVE.L   76(A1),-0x16(A0)
  631.         MOVE.W   #8,-0x2E(A0)        /* character height is 8 */
  632.         MOVE.W   #24,-0x2A(A0)       /* 25 rows on the screen */
  633.         MOVE.W   #1280,-0x28(A0)     /* 1280 bytes per screen row */
  634.       }
  635. }
  636.  
  637. mon25() {               /* switch to 25 row monochrome mode */
  638.   asm {
  639.         DC.W     0xA000
  640.         MOVE.L   8(A1),A1            /* 8x16 font */
  641.         MOVE.L   72(A1),-0x0A(A0)
  642.         MOVE.L   76(A1),-0x16(A0)
  643.         MOVE.W   #16,-0x2E(A0)       /* character height is 16 */
  644.         MOVE.W   #24,-0x2A(A0)       /* 25 rows */
  645.         MOVE.W   #1280,-0x28(A0)     /* etc. etc. left to reader */
  646.       }
  647. }
  648.  
  649. mon50() {               /* switch to 50 row monochrome mode */
  650.   asm {
  651.         DC.W     0xA000
  652.         MOVE.L   4(A1),A1
  653.         MOVE.L   72(A1),-0x0A(A0)
  654.         MOVE.L   76(A1),-0x16(A0)
  655.         MOVE.W   #8,-0x2E(A0)
  656.         MOVE.W   #43,-0x2A(A0)
  657.         MOVE.W   #720,-0x28(A0)
  658.       }
  659. }
  660.  
  661. show_emul() {                       /* display virtual video chip output */
  662.  Setscreen (scr_emul,scr_emul,-1) ;
  663.  }
  664.  
  665. show_scr() {                        /* display 6502 monitor output */
  666.   Setscreen (scr,scr,-1) ;
  667.  }
  668.  
  669. colors8() {
  670.  
  671.   if (mode==0) {
  672.    Setcolor ( 0,0x0000) ;   /* black */
  673.    Setcolor ( 3,0x0070) ;   /* green */
  674.    Setcolor ( 4,0x0070) ;
  675.    Setcolor (11,0x0740) ;   /* orange */
  676.    Setcolor (12,0x0740) ;
  677.    Setcolor ( 2,0x0405) ;   /* violet */
  678.    Setcolor ( 5,0x0405) ;
  679.    Setcolor (10,0x0007) ;   /* blue */
  680.    Setcolor (13,0x0007) ;
  681.    Setcolor ( 1,0x0777) ;
  682.    Setcolor ( 8,0x0777) ;
  683.    Setcolor ( 9,0x0777) ;
  684.    Setcolor ( 6,0x0777) ;   /* white */
  685.    Setcolor ( 7,0x0777) ;
  686.    Setcolor (14,0x0777) ;
  687.    Setcolor (15,0x0777) ;
  688.  }
  689. }
  690.  
  691. colors16() {
  692.  
  693.  if (mode==0) {
  694.    Setcolor ( 0,0x0000) ;   /* black */
  695.    Setcolor ( 1,0x0500) ;   /* magenta */
  696.    Setcolor ( 2,0x0004) ;   /* dark blue */
  697.    Setcolor ( 3,0x0405) ;   /* violet */
  698.    Setcolor ( 4,0x0030) ;   /* dark green */
  699.    Setcolor ( 5,0x0444) ;   /* grey */
  700.    Setcolor ( 6,0x0007) ;   /* blue */
  701.    Setcolor ( 7,0x0457) ;   /* light blue */
  702.    Setcolor ( 8,0x0530) ;   /* brown */
  703.    Setcolor ( 9,0x0740) ;   /* orange */
  704.    Setcolor (10,0x0222) ;   /* grey2 */
  705.    Setcolor (11,0x0745) ;   /* pink */
  706.    Setcolor (12,0x0070) ;   /* bright green */
  707.    Setcolor (13,0x0770) ;   /* yellow */
  708.    Setcolor (14,0x0055) ;   /* aqua */
  709.    Setcolor (15,0x0777) ;   /* white */
  710.  }
  711. }
  712.  
  713. /***************************************************************************/
  714.  
  715. main() {
  716.  
  717.   appl_init() ;
  718.  
  719.   scr = (char *) Physbase() ;   /* find screen memory pointer */
  720.   scr_emul = scr - 32768L ;
  721.   mem = scr - 32768L - 65536L;  /* must be on a 64K boundary!!!! */
  722.   stat = mem - 65536L + 32768L ;  /* use relative addressing */
  723.  
  724.   hardcopy = 0 ;                /* hardcopy off */
  725.   put(BEL) ;                    /* beep to announce our arrival */
  726.  
  727.   mode = Getrez() ;             /* get current screen resolution */
  728.   switch (mode) {
  729.     case 0 : col25() ;
  730.              MAXCOL = 38 ;      /* set variables used by dumping routine */
  731.              MAXROW = 24 ;
  732.              MAXBYTE = 8 ;
  733.              break ;
  734.  
  735.     case 1 : col25() ;
  736.              MAXCOL = 78 ;
  737.              MAXROW = 24 ;
  738.              MAXBYTE = 16 ;
  739.              break ;
  740.  
  741.     case 2 : mon50() ;
  742.              MAXCOL = 78 ;
  743.              MAXROW = 44 ;
  744.              MAXBYTE = 16 ;
  745.              break ;
  746.    }
  747.  
  748.   print ("\033v") ;      /* turn text wraparound on just in case */
  749.  
  750.   print ("Atari ST\277 ST Transformer Demo" ) ; CR ;
  751.   print ("\275 1986,87 Darek Mihocka") ; CR ;
  752.   print ("MegaBaud ST BBS (416)243-9519") ;
  753.   CR ;
  754.   print ("Applesoft and Integer Basic (c) Apple") ; CR ;
  755.   print ("This program is meant to be a demo and") ; CR ;
  756.   print ("not to harm Apple in any way.") ; CR ;
  757.   CR ;
  758.   print ("Release version A2.04 on Dec. 31, 1986") ; CR ;
  759.   print ("Microprocessor  : 6502 @ 250kHz") ; CR ;
  760.   print ("Hardware        : 48K Apple ][") ; CR ;
  761.   print ("Operating system: none") ; CR ;
  762.   CR ;
  763.   print ("Coming in mid-1987: The ST Transformer") ; CR ;
  764.   print ("Runs Apple, Atari 800, and Commodore 64") ; CR ;
  765.   print ("software all on the ST.") ; CR ;
  766.   CR ;
  767.  
  768.   InitMachine() ;     /* initialize virtual machine memory, pointers, etc. */
  769.  
  770.   mon() ;             /* go into monitor */
  771.  
  772.   if (mode == 2) mon25();         /* restore 25 row mode */
  773.   else col25() ;
  774.  
  775.   appl_exit() ;
  776. }
  777.  
  778.